package com.vimhe.easyimport.processor;

import com.vimhe.easyimport.config.bean.CellConfig;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 批量插入数据库工具类
 *
 * @author Vimhe
 */
public final class JdbcUtils {

    private DataSource dataSource;

    public JdbcUtils(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 批量插入
     *
     * @param tableName   表名
     * @param rowDataList 参数集合
     * @param cellConfigs 列配置
     * @throws SQLException e
     */
    public void insertBatch(String tableName, List<Map<String, Object>> rowDataList, Map<String, CellConfig> cellConfigs)
            throws SQLException {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = this.dataSource.getConnection();
            connection.setAutoCommit(false);

            String sql = generalSql(tableName, cellConfigs);
            statement = connection.prepareStatement(sql);

            for (Map<String, Object> rowData : rowDataList) {
                // 找到列对应的参数
                List<CellConfig> cellConfigList = new ArrayList<>(cellConfigs.values());
                for (int i = 0, j = cellConfigList.size(); i < j; i++) {
                    statement.setObject(i + 1, rowData.get(cellConfigList.get(i).getIndex()));
                }
                statement.addBatch();
            }

            statement.executeBatch();
            connection.commit();
        } finally {
            this.release(connection, statement, null);
        }
    }

    /**
     * 根据表名和字段配置创建插入sql语句
     *
     * @param tableName   表名
     * @param cellConfigs 字段配置
     * @return 创建的sql
     */
    private String generalSql(String tableName, Map<String, CellConfig> cellConfigs) {
        StringBuilder stringBuilder = new StringBuilder("INSERT INTO " + tableName + "(");
        StringBuilder valueBuilder = new StringBuilder(")VALUES(");
        for (CellConfig cellConfig : cellConfigs.values()) {
            stringBuilder.append(cellConfig.getColumn()).append(",");
            valueBuilder.append("?,");
        }

        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        valueBuilder.deleteCharAt(valueBuilder.length() - 1);

        stringBuilder.append(valueBuilder.toString());
        stringBuilder.append(")");

        return stringBuilder.toString();
    }

    /**
     * 释放资源
     *
     * @param connection connection
     * @param statement  statement
     * @param resultSet  resultSet
     */
    private void release(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException ignored) {
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException ignored) {
            }
        }
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException ignored) {
            }
        }
    }

}
